﻿package com.saint.bitmapDistortion 
{
	import com.saint.utils.Logger;
	import com.saint.utils.TileMaker;
	import flash.display.Bitmap;
	import flash.display.BitmapData;
	import flash.display.DisplayObject;
	import flash.display.MovieClip;
	import flash.display.Shape;
	import flash.display.Sprite;
	import flash.events.Event;
	import flash.events.MouseEvent;
	import flash.geom.Point;
	import org.flashsandy.display.DistortImage;
	/**
	 * 
	 * take in a disaply image and make it stretchable
	 * 
	 * 
	 * 
	 * 
	 * 
	 * 
	 * @author kembera
	 */
	public class StretchyImage extends Sprite
	{
		
		private var shape:Shape = new Shape();
		private var showGrid:Boolean = false;
		private var buttonAlpha:Number = 0.0;
		private var _cols:uint;
		private var _rows:uint;
		private var _tileH:Number;
		private var _tileW:Number;
		private var _buttons:Array = new Array();
		private var stretchyTiles:Array = new Array();
		private var bitmapTiles:Array = new Array(); //not Needed !!?
		private var bitmapDataTiles:Array  = new Array();
		private var resetPositions:Array = new Array();
		
		public function StretchyImage(srcDisplayObject:DisplayObject, cols:uint = 3, rows:uint= 3)
		{
			Logger.info("StretchyImage.StretchyImage " + srcDisplayObject + ", " + cols + ", " + cols);
			
			_cols = cols;
			_rows = rows;
			_tileW = srcDisplayObject.width / _cols;
			_tileH = srcDisplayObject.height / _rows;
			
			/* split the image into tiles and store as array of bitmapData*/			
			bitmapDataTiles= TileMaker.makeTiles(srcDisplayObject, cols, rows);
			Logger.debug("StretchyImage.StretchyImage bitmapData tiles made: " + bitmapDataTiles.length);
			
			/* create an array of bitmaps */
			for (var i:Number = 0; i < bitmapDataTiles.length; i++)
			{
				bitmapTiles.push(new Bitmap(bitmapDataTiles[i]));
			}
			
			/* create an array to hold the stretychImage tiles */
			var width:Number;
			var height:Number;
			for (var n:Number = 0; n <bitmapTiles.length; n++)
			{
				width = Bitmap(bitmapTiles[n]).width;
				height = Bitmap(bitmapTiles[n]).height;
				var distortionTile:DistortImage = new DistortImage(width, height, 1, 1);
				stretchyTiles.push(distortionTile);
			}
			
			
			/* create the buttons */
			createButtons();
			
			layoutButtons();
			
			/* add the holding shape to the stage */
			this.addChild(shape);			
			
			addEventListener(Event.ENTER_FRAME, onEnterFrame);
			
			//onEnterFrameP(null);
		}
		
		
		/**
		 * HERE'S THE SCIENCE BIT
		 * 
		 * tells each stretch tile is it's corners
		 * 	
		 * @param	e
		 */
		private function onEnterFrame(e:Event):void 
		{
			this.shape.graphics.clear();
			this.setChildIndex(shape, 0);
			//this.shape.alpha = 0.2;
			
			
			if (this.showGrid){
				this.shape.graphics.lineStyle(1, 0xffcc00);
			}			
			
			var topLeft:MovieClip;
			var topRight:MovieClip;
			var bottomLeft:MovieClip;
			var bottomRight:MovieClip;
			
			var topLeftNum:Number ; 
			var bottomLeftNum: Number ;
			var topRightNum:Number ;					
			var bottomRightNum:Number ;
				
			for (var i:Number = 0; i < _rows; i++)
			{			
				for (var n:Number = 0; n < _cols; n++)
				{			
					var col:Number = n;
					var row:Number = i;
					
					var index:Number = n + (i * (_cols));
					
					topLeftNum= ((_cols+1) * i ) + n
					bottomLeftNum= ((_cols+1) * i) + (_cols + 1) + n;
					topRightNum= topLeftNum + 1;					
					bottomRightNum=  bottomLeftNum + 1;
					
					topLeft = _buttons[topLeftNum];
					bottomLeft = _buttons[bottomLeftNum];
					topRight = _buttons[topRightNum];
					bottomRight = _buttons[bottomRightNum];
				 
					DistortImage(stretchyTiles[i]).setTransform(this.shape.graphics, 
																	BitmapData(this.bitmapDataTiles[index]),
																	this.getDisplayObjectCenter(topLeft, 0, 0),
																	this.getDisplayObjectCenter(topRight, 0, 0),
																	this.getDisplayObjectCenter(bottomRight, 0, 0),
																	this.getDisplayObjectCenter(bottomLeft, 0, 0));
																	
				}
			}
				
			
			/*distortion1.setTransform(this.shape.graphics, 
						this.bitmap1.bitmapData, 
						this.getDisplayObjectCenter(this.dragBtn1, -50, -50), 
						this.getDisplayObjectCenter(this.dragBtn2, -50, -50), 
						this.getDisplayObjectCenter(this.dragBtn3, -50, -50), 
						this.getDisplayObjectCenter(this.dragBtn4, -50, -50));*/
		}
		
		/**
		 * lays out the buttons on the stage
		 * 
		 * 	0	-	1	-	2	-	3	-	4
		 * 
		 * 	5	-	6	-	7	-	9	-	10
		 * 
		 * 	1	-	12	-	13	-	14	-	15
		 * 
		 * 
		 */
		private function layoutButtons():void
		{
			Logger.info("StretchyImage.layoutButtons");
			for (var i:Number = 0; i <= _rows; i++)
			{
				for (var n:Number = 0; n <= _cols; n++)
				{
					var index:Number = n + (i * (_cols + 1));
					var pnt:Point = new Point(n * _tileW,i * _tileH)
					_buttons[index].x = pnt.x;  
					_buttons[index].y = pnt.y;  
					_buttons[index].alpha = buttonAlpha; 
					resetPositions.push(pnt);
					addChild(_buttons[index]);
				}
			}
			
		}
		
		
		/**
		 * creates the dragale buttons that the bitmap tiles area attached to
		 * 
		 * this uses a library asset attached as DragButton
		 * 
		 */
		private function createButtons():void
		{
			Logger.info("StretchyImage.createButtons");
			
			var dragBtn:MovieClip;
			for (var i:Number = 0; i < (_cols + 1) * (_rows + 1); i++)
			{
				dragBtn = new DragButton()
				//dragBtn.label.text = i;
				_buttons.push(dragBtn);
				dragBtn.addEventListener(MouseEvent.MOUSE_DOWN, startButtonDrag);
				dragBtn.addEventListener(MouseEvent.MOUSE_UP, stopButtonDrag);	
			}
		}
		
		//TODO - look at what x and y are needed for
		private function getDisplayObjectCenter (child:DisplayObject, x:Number=0, y:Number=0):Point {
			var center:Point = new Point();
			center.x = child.x + child.width/2 + x;
			center.y = child.y + child.height/2 + y;
			return center;
		}
		
		
		
		
		/**
		 * stop button drag
		 * @param	e
		 */
		private function stopButtonDrag(e:MouseEvent):void 
		{
			e.target.stopDrag();
		}
		
		/**
		 * start button brag
		 * @param	e
		 */
		private function startButtonDrag(e:MouseEvent):void 
		{
			e.target.startDrag(false);
		}
		
		public function reset():void
		{
			for (var i:Number = 0 ; i <  _buttons.length;i++ )
			{
				_buttons[i].x = resetPositions[i].x;
				_buttons[i].y = resetPositions[i].y;
			}
		}
		
		public function get cols():uint { return _cols; }
		
		public function get rows():uint { return _rows; }
		
		public function get buttons():Array { return _buttons; }
		
	}

}